#!/usr/bin/env python
# coding:utf-8
# Author: mingzhong.huang

import json
import requests
from datetime import datetime

from yagmail import SMTP

from core.celery import celery_app
from core.logger import logger
from setting import config


class NoticeTools():
    def __init__(self):
        self.url = config.SA_API
        self.token = config.SA_TOKEN
        self.chat_group_id = config.SA_CHAT_GROUP_ID
        self.user_agent = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'
        self.headers = {
            "User-Agent": self.user_agent, "Connection": "keep-alive",
            "Content-Type": "application/json",
            "authorization": self.token
        }

    def send_wechat(self, user_list, content=None, msgtype="text"):
        """
        发个人企业微信，支持 markdown 和 text
        """
        url = self.url + "/api/tasks/wechat/send"
        data = {
            "config": {
                "user_list": user_list,
                "content": content,
                "msgtype": msgtype
            }
        }
        try:
            req = requests.post(url=url, headers=self.headers, data=json.dumps(data))
            if req.status_code != 200:
                logger.error(f"send wechat failed, user_list:{user_list} reason:{req.text}")
                return False
        except Exception as e:
            logger.error(f"send wechat: {user_list} error =>{e}")
            return False
        logger.info(f"send wechat success => {user_list}")
        return True



    def send_wechat_group(self, content=None):
        url = self.url + "/api/tasks/wechat/push"
        data = {
            "config": {
                "chatid": self.chat_group_id,
                "content": content
            }
        }
        try:
            req = requests.post(url=url, headers=self.headers, data=json.dumps(data))
            if req.status_code != 200:
                logger.error(f"send wechat group failed")
                return False
        except Exception as e:
            logger.error(f"send wechat group error =>{e}")
            return False
        logger.info(f"send wechat group success")
        return True



    def send_wechat_card(self, data):
        """
        发送企业微信小程序的卡片信息
        """
        url = config.WBOT_API + "webhook"
        headers = {
            "User-Agent": self.user_agent, "Connection": "keep-alive",
            "Content-Type": "application/json",
            "Authorization": "APPCODE 32aaa464cd8449cfb17f4a50ed988b8c"
        }

        try:
            req = requests.post(url=url, headers=headers, data=json.dumps(data))
            if req.status_code != 200:
                logger.error(f"send wechat card failed")
                return False
        except Exception as e:
            logger.error(f"send wechat card error =>{e}")
            return False
        logger.info(f"send wechat card success")
        return True



    @staticmethod
    def send_wechatbot(key, content, msgtype="markdown", protocol="https", host="qyapi.weixin.qq.com"):
        """
        发送微信机器人群，支持 markdown 和 text
        """

        url = f"{protocol}://{host}/cgi-bin/webhook/send?key={key}"
        headers = {'Content-Type': 'application/json'}

        payload = json.dumps({
            "msgtype": msgtype,
            "markdown": {
                "content": content
            }
        })

        try:
            req = requests.post(url=url, headers=headers, data=payload)
            if req.status_code != 200:
                logger.error(f"send wechat bot fail {content} => {req.json()}")
                return {}
        except Exception as e:
            logger.error(f"send wechat bot exception {content} => {e}")
            return {}
        logger.info(f"send wechat bot success => {content}")
        return req.json()




    def send_sms(self, mobiles, content=None):
        url = self.url + "/api/tasks/sms/send"
        data = {
            "mobiles": mobiles,
            "text": content
        }
        try:
            if not mobiles:
                logger.error(f"mobiles:{mobiles}, do nothing")
                return True
            
            req = requests.post(url=url, headers=self.headers, data=json.dumps(data))
            if req.status_code != 200:
                logger.error(f"send sms failed => {mobiles}")
                return False
        except Exception as e:
            logger.error(f"send sms: {mobiles} error =>{e}")
            return False
        logger.info(f"send sms success => {mobiles}")
        return True




    def send_voice(self, users):
        self.send_aliyun_voice(users)
        
        url = self.url + "/api/tasks/voice/send"
        data = {
            "users": users,
            "text": "应用服务故障，请紧急处理"
        }
        try:
            if not users:
                logger.error(f"users:{users}, do nothing")
                return True
            
            req = requests.post(url=url, headers=self.headers, data=json.dumps(data))
            if req.status_code != 200:
                logger.error(f"send voice failed => {users}")
                return False
        except Exception as e:
            logger.error(f"send voice: {users} error =>{e}")
            return False
        logger.info(f"send voice success => {users}")
        return True





    def send_aliyun_voice(self, users):
        #内网地址：    http://metrichub-cn-shenzhen.aliyun.com
        url = "https://metrichub-cms-cn-hangzhou.aliyuncs.com/event/notify?token=eyJhbGlVaWQiOiIxNDkyOTA2ODExNTY5MTAwIiwibmFtZSI6Iui_kOe7tOe7hCIsInNlY3VyZSI6IjMzNDhkYzlkLWQxZjYtNDg3Mi05NjFmLWI1ZGRiYzQ1Y2U0OSIsInRva2VuVHlwZSI6ImNvbnRhY3RHcm91cCJ9.zaQDA4rTjbpmERfg9fH9ZQ&level=CRITICAL"
        data = {
            "ruleName": "业务电话告警",
            "title": "业务电话告警",
            "message": "服务故障, 请紧急处理5zJ7El0XYw2a"
        }
        try:
            headers = {
                "Content-Type": "application/json"
            }
            req = requests.post(url=url, headers=headers, data=json.dumps(data))
            if req.status_code != 200:
                logger.error(f"send aliyun voice failed => {users}")
                return False
        except Exception as e:
            logger.error(f"send aliyun voice: {users} error =>{e}")
            return False
        logger.info(f"send aliyun voice success => {users}")
        return True




    @staticmethod
    @celery_app.task(bind=True)
    def email(self, to_users: list, subject: str, body: str = "", html: str = "", host=config.EMAIL_HOST,
              port=config.EMAIL_PORT, username=config.EMAIL_USERNAME, password=config.EMAIL_PASSWORD, smtp_ssl=True):
        yag = SMTP(host=host, port=port, user=username, password=password, smtp_ssl=smtp_ssl)
        try:
            yag.send(to=to_users, subject=subject, contents=[body, html])
            logger.info("send email success")
            return True
        except Exception as e:
            logger.error(f"send email error =>{e}")
            return False



    def alarm_level_to_chinese(self, level):
        mapp_data = {
            "critical": "紧急",
            "major": "重要",
            "warning": "一般",
            "info": "信息",
            "nothing": "无"
        }
        return mapp_data.get(level, "无")




    def alarm_message(self, alert_info, notice_info, record_info):
        if alert_info["status"] == 'firing':
            status = '告警'
        else:
            status = '恢复'
        create_time = datetime.strftime(datetime.now(), "%Y-%m-%d %H:%M:%S")
        notice_user = "@" + "@".join(notice_info["chat_users"])
        level = self.alarm_level_to_chinese(alert_info["labels"]["i_level"])
        msg = '【' + status + '】 From prometheus' + '\n' \
              + '告警类型：' + alert_info["labels"]["i_classes"] + '\n' \
              + '告警名称：' + alert_info["labels"]["alertname"] + '\n' \
              + '告警目标：' + alert_info["labels"]["i_target"] + '\n' \
              + '告警详情：' + alert_info["annotations"]["message"] + '\n' \
              + '告警阀值：' + alert_info["annotations"]["value"] + '\n' \
              + '告警级别：' + level + '\n' \
              + '告警次数：' + str(record_info["number"]) + '\n' \
              + '告警指纹：' + f"{alert_info['fingerprint']}+{record_info['uuid']}" + '\n' \
              + '告警时间：' + create_time + '\n' \
              + '通知人员：' + notice_user + '\n' \
              + '查看地址：' + alert_info["short_url"] + '\n'

        return msg



    def alarm_message_markdown(self, alert_info, record_info):
        if alert_info["status"] == 'firing':
            status = '<font color="warning">告警</font> '
        else:
            status = '<font color="info">恢复</font> '

        level = self.alarm_level_to_chinese(alert_info["labels"]["i_level"])
        level = f'<font color="warning">{level}</font>'

        create_time = datetime.strftime(datetime.now(), "%Y-%m-%d %H:%M:%S")
        msg = '## 【' + status + '】 From prometheus' + '\n' \
              + '> 告警类型：' + alert_info["labels"]["i_classes"] + '\n' \
              + '> 告警名称：' + alert_info["labels"]["alertname"] + '\n' \
              + '> 告警目标：' + alert_info["labels"]["i_target"] + '\n' \
              + '> 告警详情：' + alert_info["annotations"]["message"] + '\n' \
              + '> 告警阀值：' + alert_info["annotations"]["value"] + '\n' \
              + '> 告警级别：' + level + '\n' \
              + '> 告警次数：' + str(record_info["number"]) + '\n' \
              + '> 告警指纹：' + alert_info["fingerprint"] + '\n' \
              + '> 告警时间：' + create_time + '\n' \
              + '> 查看地址：' + alert_info["short_url"] + '\n'

        return msg



    def alarm_message_card(self, alert_info, notice_info, record_info):
        if alert_info["status"] == 'firing':
            status = '告警'
        else:
            status = '恢复'
            
        data = {
            "chat_id": config.WBOT_CHAT_BOT_ID,
            "type": "基础告警",
            "target": alert_info["labels"]["i_target"],
            "level": alert_info["labels"]["i_level"],
            "emphasis_content": {
                "title": status,
                "desc": f"告警次数:{record_info['number']}"
            },
            "horizontal_content_list": [
                {
                    "keyname": "告警类型",
                    "value": alert_info["labels"]["i_classes"]
                },
                {
                    "keyname": "告警规则",
                    "value": alert_info["labels"]["alertname"]
                },
                {
                    "keyname": "告警阀值",
                    "value": alert_info["annotations"]["value"]
                },
                {
                    "keyname": "告警指纹",
                    "value": f"{alert_info['fingerprint']}-{record_info['uuid']}"
                },
                {
                    "keyname": "通知人员",
                    "value": "@"+"@".join(notice_info["chat_users"])
                },
                {
                    "keyname": "查看地址",
                    "value": "点击访问",
                    "type": 1,
                    "url": alert_info["short_url"]
                }
            ],
            "content": alert_info["annotations"]["message"]
        }
        
        return data




    def n9e_alarm_message(self, alert_info, notice_info, record_info):
        if alert_info["status"] == 'firing':
            status = '告警'
        else:
            status = '恢复'
        create_time = datetime.strftime(datetime.now(), "%Y-%m-%d %H:%M:%S")
        notice_user = "@" + "@".join(notice_info["chat_users"])
        level = self.alarm_level_to_chinese(alert_info["level"])
        msg = '【' + status + f'】 From {config.NOTICE_CENTER_N9E_NAME}' + '\n' \
              + '告警集群：' + alert_info["cluster"] + '\n' \
              + '告警类型：' + alert_info["notice_type"] + '\n' \
              + '告警名称：' + alert_info["name"] + '\n' \
              + '告警目标：' + alert_info["target"] + '\n' \
              + '告警详情：' + alert_info["annotations"] + '\n' \
              + '告警阀值：' + alert_info["value"] + '\n' \
              + '告警级别：' + level + '\n' \
              + '告警次数：' + str(record_info["number"]) + '\n' \
              + '告警指纹：' + f"{alert_info['fingerprint']}+{record_info['uuid']}" + '\n' \
              + '告警时间：' + create_time + '\n' \
              + '通知人员：' + notice_user + '\n'

        return msg



    def n9e_alarm_message_markdown(self, alert_info, notice_info, record_info):
        if alert_info["status"] == 'firing':
            status = '<font color="warning">告警</font> '
        else:
            status = '<font color="info">恢复</font> '

        level = self.alarm_level_to_chinese(alert_info["level"])
        level = f'<font color="warning">{level}</font>'

        create_time = datetime.strftime(datetime.now(), "%Y-%m-%d %H:%M:%S")
        notice_user = "@" + "@".join(notice_info["chat_users"])
        msg = '## 【' + status + f'】 From {config.NOTICE_CENTER_N9E_NAME}' + '\n' \
              + '> 告警集群：' + alert_info["cluster"] + '\n' \
              + '> 告警类型：' + alert_info["notice_type"] + '\n' \
              + '> 告警名称：' + alert_info["name"] + '\n' \
              + '> 告警目标：' + alert_info["target"] + '\n' \
              + '> 告警详情：' + alert_info["annotations"] + '\n' \
              + '> 告警阀值：' + alert_info["value"] + '\n' \
              + '> 告警级别：' + level + '\n' \
              + '> 告警次数：' + str(record_info["number"]) + '\n' \
              + '> 告警指纹：' + alert_info["fingerprint"] + '\n' \
              + '> 告警时间：' + create_time + '\n' \
              + '> 通知人员：' + notice_user + '\n'

        return msg



    def n9e_alarm_message_card(self, alert_info, notice_info, record_info):
        if alert_info["status"] == 'firing':
            status = '告警'
        else:
            status = '恢复'
            
        data = {
            "chat_id": "",
            "refer": config.NOTICE_CENTER_N9E_NAME,
            "type": "n9e告警",
            "target": alert_info["target"],
            "level": alert_info["level"],
            "emphasis_content": {
                "title": status,
                "desc": f"告警次数:{record_info['number']}"
            },
            "horizontal_content_list": [
                {
                    "keyname": "告警集群",
                    "value": alert_info["cluster"]
                },
                {
                    "keyname": "告警类型",
                    "value": alert_info["notice_type"]
                },
                {
                    "keyname": "告警规则",
                    "value": alert_info["name"]
                },
                {
                    "keyname": "告警阀值",
                    "value": alert_info["value"]
                },
                {
                    "keyname": "告警指纹",
                    "value": f"{alert_info['fingerprint']}-{record_info['uuid']}"
                },
                {
                    "keyname": "通知人员",
                    "value": "@"+"@".join(notice_info["chat_users"])
                }
            ],
            "finger_print": f"{alert_info['fingerprint']}-{record_info['uuid']}",
            "content": alert_info["annotations"]
        }
        
        return data








    def log_alarm_message(self, notice_strategy, notice_info, record_info):
        """
        日志告警信息拼装文本格式
        """
        alert_info = record_info["alarm_infos"][-1]
        time_interval = f"{alert_info['cst_begin_time']}~{alert_info['cst_end_time']}"
        notice_user = "@" + "@".join(notice_info["chat_users"])
        level_chinese = self.alarm_level_to_chinese(notice_strategy["level"])
        msg = f'【告警】 From {config.NOTICE_CENTER_LOG_NAME}' + '\n' \
              + '告警服务：' + notice_strategy["name"] + '\n' \
              + '错误计数：' + str(alert_info["error_count"]) + '\n' \
              + '告警详情：' + alert_info["error_message"][:50] + '\n' \
              + '告警级别：' + level_chinese + '\n' \
              + '告警次数：' + str(record_info["alarm_count"]) + '\n' \
              + '告警指纹：' + record_info["fingerprint"] + '\n' \
              + '通知人员：' + notice_user + '\n' \
              + '时间区间：' + time_interval + '\n' \
              + '查看地址：' + alert_info["app_url"] + '\n'

        return msg



    def log_alarm_message_markdown(self, notice_strategy, notice_info, record_info):
        """
        日志告警信息拼装markdown格式
        """
        alert_info = record_info["alarm_infos"][-1]
        time_interval = f"{alert_info['cst_begin_time']}~{alert_info['cst_end_time']}"
        notice_user = "@" + "@".join(notice_info["chat_users"])
        level_chinese = f'<font color="warning">{self.alarm_level_to_chinese(notice_strategy["level"])}</font>'
        msg = f'## 【<font color="warning">告警</font>】 From {config.NOTICE_CENTER_LOG_NAME}' + '\n' \
              + '> 告警服务：' + notice_strategy["name"] + '\n' \
              + '> 错误计数：' + str(alert_info["error_count"]) + '\n' \
              + '> 告警详情：' + alert_info["error_message"] + '\n' \
              + '> 告警级别：' + level_chinese + '\n' \
              + '> 告警次数：' + str(record_info["alarm_count"]) + '\n' \
              + '> 告警指纹：' + record_info["fingerprint"] + '\n' \
              + '> 通知人员：' + notice_user + '\n' \
              + '> 时间区间：' + time_interval + '\n' \
              + '> 查看地址：' + alert_info["app_url"] + '\n'

        return msg



    def log_alarm_message_card(self, notice_strategy, notice_info, record_info):
        """
        日志告警信息拼装card格式
        """
        alert_info = record_info["alarm_infos"][-1]
        time_interval = f"{alert_info['cst_begin_time']}~{alert_info['cst_end_time']}"
        notice_user = "@" + "@".join(notice_info["chat_users"])
        level_chinese = self.alarm_level_to_chinese(notice_strategy["level"])
        data = {
            "chat_id": "",
            # HuaweiProdLog HuaweiProdN9e
            "refer": config.NOTICE_CENTER_LOG_NAME,
            "type":"日志告警",
            "target": notice_strategy["name"],
            "level": level_chinese,
            "emphasis_content": {
                "title": "告警",
                "desc": f"ERROR级别日志条数:{alert_info['error_count']}" 
            },
            "horizontal_content_list": [
                {
                    "keyname": "告警来源",
                    "value": config.NOTICE_CENTER_LOG_NAME
                },
                {
                    "keyname": "时间区间",
                    "value": time_interval
                },
                {
                    "keyname": "告警知会人",
                    "value": notice_user
                },
                {
                    "keyname": "告警次数",
                    "value": str(record_info["alarm_count"])
                },
                {
                    "keyname": "告警指纹",
                    "value": record_info["fingerprint"]
                },
                {
                    "keyname": "查看地址",
                    "value": "点击访问",
                    "type": 1,
                    "url": alert_info["app_url"]
                },
            ],
            "content": alert_info["error_message"]
        }
        
        return data




def main():
    notice_tools = NoticeTools()
    # #, {'username': 'caitlyn.liu', 'mobile': '15797900836'}, {'username': 'charles.fang', 'mobile': '13760677606'}
    #users = [{'username': 'caitlyn.liu', 'mobile': '18926017545'},{'username': 'caitlyn.liu', 'mobile': '18682003157'}]
    users = [{'username': 'mingzhong.huang', 'mobile': '18682003157'}, {'username': 'daniel.dong', 'mobile': '13058053127'}]
    notice_tools.send_voice(users)

    # alert_info = {
    #     "status": "firing",
    #     "labels": {
    #         "i_classes": "K8s资源",
    #         "alertname": "K8sResourcesDeploymentAvailableMismatch",
    #         "i_target": "K8sDeployment",
    #         "i_level": "comment"
    #     },
    #     "annotations": {
    #         "message": "Deployment prod/welab-skyscanner-tenma 有异常节点",
    #         "value": "6"
    #     },
    #     "fingerprint": "0f77a5ea7f35ac06",
    #     "short_url": "https://devops.welab-inc.com/ops/api/v1/tools/url_shorten/redirect?short_link=06dSWqxHeuf8HqPuEHlX_mRDrQ8PgIDuEWGTJ7Eg4js="
    # }
    # notice_info = {
    #     "chat_users": ["sumi.wang", "boll.lai", "mingzhong.huang"]
    # }
    # record_info = {
    #     "number": 20,
    #     "uuid": 11646
    # }
    
    
    # data = {
    #     "chat_id": "5c0a9d37-0722-42f2-8727-1a4d5b61e94b",
    #     "refer": "n9e",
    #     "type": "n9e告警",
    #     "target": "test",
    #     "level": "warning",
    #     "emphasis_content": {
    #             "title": "告警",
    #             "desc": "告警次数:3"
    #     },
    #     "horizontal_content_list": [
    #             {
    #                     "keyname": "告警集群",
    #                     "value": "n9e"
    #             },
    #             {
    #                     "keyname": "告警类型",
    #                     "value": "alarm"
    #             },
    #             {
    #                     "keyname": "告警规则",
    #                     "value": "DeploymentUnavilable"
    #             },
    #             {
    #                     "keyname": "告警阀值",
    #                     "value": "1"
    #             },
    #             {
    #                     "keyname": "告警指纹",
    #                     "value": "9094-492c-85dd-19bcf47183ff"
    #             },
    #             {
    #                     "keyname": "通知人员",
    #                     "value": "@Daniel"
    #             }
    #     ],
    #     "finger_print": "9094-492c-85dd-19bcf47183ff",
    #     "content": "测试"
    # }
    # notice_tools.send_wechat_card(data)


if __name__ == "__main__":
    main()
